﻿/****************************************************************************
Copyright (c) 2014-2015 凌惊雪 微信:Lingjingxue 邮箱:lingjingxue@sina.com QQ:271487457

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

using ServerBase.Config;
using UtilPublic.Mysql;
using ServerBase.DataBaseRedis;
using ServerBase.IniFile;
using UtilPublic.ServerLoger;
using ServerBase.Service;
using System;
using System.IO;
using System.Xml;
using UtilLib;
using static ServerBase.Config.Conf;
using static ServerBase.IniFile.IniConf;
using System.Text;
using System.Threading;
using UtilPublic.Serialization;
using ServerBase.Other;
using System.Collections.Generic;
using UtilPublic.Redis;
using ServerBase.LunarSocket;
using System.Threading.Tasks;

namespace ServerBase.Service
{
    public static class BaseProgram
    {
        //单机模式
        public static readonly bool StandAloneMode = true;
        public static bool PubMain1(string[] args)
        {
            #region 设置窗口属性

            Console.Title = BaseServerInfo.ServerType.ToString();
            //Console.SetWindowSize(160, 30);
            //Console.SetBufferSize(160, 9600);

            #endregion 设置窗口属性

            #region 解析命令行参数

            if (true)
            {
                var stringargs = string.Join(" ", args);
                Util.Show($"使用程序 命令行参数 {stringargs}");
                string cmdargs = "";
                foreach (var arg in args)
                {
                    //服务器
                    if (arg.StartsWith("Server"))
                    {
                        var argtemp = arg.Substring(6);
                        BaseServerInfo.ConfigId = argtemp.ToInt();
                        cmdargs += $" 服务器ID{BaseServerInfo.ConfigId}";
                    }
                    //配置目录
                    if (arg.StartsWith("Config"))
                    {
                        var argtemp = arg.Substring(6);
                        BaseServerInfo.ServerConfigDir = argtemp;
                        cmdargs += $" 服务器配置目录{BaseServerInfo.ServerConfigDir}";
                    }
                }
                Util.Show($"命令行参数 {cmdargs}");
            }


            #endregion

            #region 读取服务器基础配置
            //读取服务器基础配置
            Conf.InitConfSystem(); 
            #endregion

            #region 根据命令行参数重新配置服务器

            //服务器
            if (!ConfToolServerGame.TryGetValue(BaseServerInfo.ConfigId, out BaseServerInfo.Cfg))
            {
                Util.ShowError($"找不到服务器配置 BaseServerInfo.ConfigId{BaseServerInfo.ConfigId}");
                Console.ReadKey();
                return false;
            }
            //平台
            if (!ConfToolServerPlatformExt.TryGetValue(BaseServerInfo.ServerPlatform, out BaseServerInfo.CfgPlatform))
            {
                loger.Fatal("获取服务器平台配置 失败");
                Console.ReadKey();
                return false;
            }
            BaseServerInfo.MysqlState = BaseServerInfo.CfgPlatform.MysqlState;
            BaseServerInfo.RestrictLogin = BaseServerInfo.Cfg.RestrictLogin;

            //单机模式不使用mysql
            BaseServerInfo.MysqlState = !StandAloneMode;

            #region 判断本地IP地址是否符合配置表里的对外IP
            //非本机调试 判断本地IP地址是否符合配置表里的对外IP 符合才能启动
            if (BaseServerInfo.判断本地IP地址是否符合配置表里的对外IP)
            {
                if (BaseServerInfo.ServerRunMode != EServerRunMode.本机调试)
                {
                    if (BaseServerInfo.ServerType == EServerType.游戏)
                    {
                        try
                        {
                            var PathCurrent = Directory.GetCurrentDirectory();
                            FileStream fs_PTL = new FileStream(PathCurrent + @"\zzz.txt", FileMode.Open);
                            StreamReader sr_PTL = new StreamReader(fs_PTL, Encoding.Default);

                            string LineText = null;
                            if ((LineText = sr_PTL.ReadLine()) != null)
                            {
                                BaseServerInfo.LocalIp = LineText;
                            }

                            sr_PTL.Close();
                        }
                        catch
                        {
                            Util.ShowError($"本地IP地址文件匹配错误 zzz.txt");
                            Console.ReadKey();
                            return false;
                        }
                        if (BaseServerInfo.LocalIp != BaseServerInfo.Cfg.ServerIp)
                        {
                            Util.ShowError($"不匹配的本地IP地址 {BaseServerInfo.LocalIp} != {BaseServerInfo.Cfg.ServerIp}");
                            Console.ReadKey();
                            return false;
                        }
                    }
                }
            } 
            #endregion


            if (Util.PortInUse(BaseServerInfo.ServerPort))
            {
                Util.ShowError($"端口被占用 {BaseServerInfo.ServerPort}");
                Console.ReadKey();
                return false;
            }

            #endregion 根据命令行参数重新配置服务器

            #region 初始化日志系统

            bool log4net_init = false;
            while (!log4net_init)
            {
                try
                {
                    var log4netXmlFs = new FileStream("Conf_Log//log4net_tpl.config", FileMode.Open);
                    var log4netXmlSr = new StreamReader(log4netXmlFs);
                    var log4netXmlStr = log4netXmlSr.ReadToEnd();
                    log4netXmlStr = log4netXmlStr.Replace("$$$$$", $"{BaseServerInfo.ServerType}{BaseServerInfo.ConfigId}");
                    log4netXmlSr.Close();
                    var log4netXmlDoc = new XmlDocument();
                    log4netXmlDoc.LoadXml(log4netXmlStr);
                    var log4netRootElement = log4netXmlDoc.DocumentElement;
                    loger.Configure("NETCoreRepository", log4netRootElement);
                    log4net_init = true;
                }
                catch (Exception ex)
                {
                    Util.ShowError($"初始化日志系统错误 {BaseServerInfo.ServerPort} {ex.Message}");
                    break;
                }
            }

            #endregion 初始化日志系统

            #region 读取游戏配置文件

            if (BaseServerInfo.ServerType == EServerType.游戏)
            {
                Util.Show("读取游戏配置文件......");
                if (InitConf())
                {
                    loger.Info("初始化配置文件成功");
                }
                else
                {
                    loger.Fatal("初始化配置文件失败");
                    Console.ReadKey();
                    return false;
                }
            }

            #endregion 读取游戏配置文件

            #region 读取INI配置文件

            Util.Show("读取INI配置文件 ......");
            if (IniConf.InitIniConf())
            {
                loger.Info("读取INI配置文件 成功");
            }
            else
            {
                loger.Fatal("读取INI配置文件 失败");
                Console.ReadKey();
                return false;
            }

            #endregion 读取游戏配置文件

            

            return true;
        }

        public static void PubMain2()
        {
            #region 连接到Mysql数据库

            var ConfMysql = BaseServerInfo.CfgPlatform;
            if (BaseServerInfo.MysqlState)
            {
                //主线程数据库链接
                BaseServerInfo.DbMysqlMain = new DbMysql(ConfMysql.MysqlDataSource, ConfMysql.MysqlPort, ConfMysql.MysqlUserId, ConfMysql.MysqlPassword, ConfMysql.MysqlDatabase);
                BaseServerInfo.DbMysqlMain.DbMysqlConnect();

                //添加数据库的写入线程
                BaseServerInfo.ListTasks.Add(Task.Run(() => 
                {
                    var cfg = BaseServerInfo.CfgPlatform;
                    DbMysqlSecond.ThreadDbMysqlSecondStart(cfg.MysqlDataSource, cfg.MysqlPort, cfg.MysqlUserId, cfg.MysqlPassword, cfg.MysqlDatabase);
                }));

            }

            #endregion 连接到Mysql数据库

            #region 连接到Redis

            if (true)
            {
                var cfgRedis = BaseServerInfo.CfgPlatform;
                ServerRedis.RedisGame.Setup(cfgRedis.RedisName, cfgRedis.RedisHost, cfgRedis.RedisPort, cfgRedis.RedisPassword, cfgRedis.RedisDbIndex);
                //单机模式redis链接本机
                if (StandAloneMode)
                {
                    ServerRedis.RedisGame.Setup(cfgRedis.RedisName, "127.0.0.1", cfgRedis.RedisPort, cfgRedis.RedisPassword, cfgRedis.RedisDbIndex);
                }
                if (ServerRedis.RedisGame.Connect())
                {
                    loger.Info($"{ServerRedis.RedisGame.Name} 连接成功");
                }
                else
                {
                    loger.Fatal($"{ServerRedis.RedisGame.Name} 连接失败");
                    Console.ReadKey();
                    return;
                }
            }

            #endregion 连接到Redis

            //记录启动时间
            BaseServerInfo.ServerStartupTime = DateTime.Now;
        }



    }
}
